home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / network / ncsasock / rexec.c < prev    next >
Text File  |  1996-07-05  |  5KB  |  228 lines

  1. /*
  2.  * BSD-style socket emulation library for the Mac
  3.  * Original author: Tom Milligan
  4.  * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
  5.  *
  6.  * This source file is placed in the public domian.
  7.  * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
  8.  *
  9.  *      National Center for Supercomputing Applications
  10.  *      152 Computing Applications Building
  11.  *      605 E. Springfield Ave.
  12.  *      Champaign, IL  61820
  13.  */
  14.  
  15. /*
  16.  * rexec.c
  17.  * Mac implimentation of rexec. Uses NCSA MacTCP sockets.
  18.  * Written by Charlie Reiman - Tom actually had nothing to do with this file
  19.  * Started Friday, July 13, 1990 10:04:33 AM
  20.  */
  21.  
  22. # include <Events.h>
  23. # include <Types.h>
  24. # include <Stdio.h>
  25.  
  26. # include <s_types.h>
  27. # include <netdb.h>
  28. # include <neti_in.h>
  29. # include <s_socket.h>
  30. # include <s_time.h>
  31. # include <neterrno.h>
  32. #ifdef COMP_CODEWAR
  33. #define    EACCES        13        /* Permission denied */
  34. #endif
  35. # include <string.h>
  36.  
  37. # include <MacTCPCommonTypes.h>
  38.  
  39. #include "rexec.h"
  40. #include "unixlib.h" /* dgg */
  41. #include "sock_ext.h"        /* uses only high level calls */
  42.  
  43. #define BUFZ 256
  44.  
  45. #ifndef min
  46. #define min(a,b) ( ( a < b ) ? a : b )
  47. #endif
  48.  
  49. #define NIL NULL
  50. #define DOERR    if ( anErr < 0 ) return anErr;
  51.  
  52. #ifndef _ERRNO
  53. extern    int    errno;
  54. #endif
  55.  
  56. int rexec(
  57.     char **ahost,
  58.     Int4 inport,
  59.     char *user,
  60.     char *passwd,
  61.     char *cmd,
  62.     int *fd2p)
  63.     
  64.     {
  65.     struct    hostent *hp;
  66.     struct  sockaddr_in    sa,me,her;
  67.     int        sockOut;
  68.     int        anErr;        /* an error? */
  69.     Int4     herlen = sizeof(her),melen;
  70.     char    wbuf[BUFZ];
  71.     
  72.     
  73.     hp=gethostbyname(*ahost);
  74.  
  75.  
  76.     if ( hp == NULL )
  77.         {
  78.         int        a,b,c,d;
  79.         
  80.         if ( sscanf(*ahost,"%d.%d.%d.%d",&a,&b,&c,&d) != 4 )
  81.             {
  82.             errno = errno_long = EHOSTUNREACH;
  83.             return -1;
  84.             }
  85.         else
  86.             {
  87.             herlen = (a<<24) | ( b<<16) | (c<<8) | (d);
  88.             bcopy((char*)&herlen,(char*)&sa.sin_addr,4);
  89.             }
  90.         }
  91.     else
  92.         bcopy((char*)hp->h_addr,(char*)&sa.sin_addr,hp->h_length);
  93.  
  94.     
  95.     sa.sin_port=htons(inport);
  96.     sa.sin_family=AF_INET;
  97.  
  98.     sockOut=s_socket(AF_INET,SOCK_STREAM,0);
  99.     
  100.     if (sockOut<0)
  101.         {
  102.         return -1;
  103.         }
  104.     
  105.     if (s_connect(sockOut,(struct sockaddr *)&sa,sizeof(sa))<0)
  106.         {
  107.         return -1;
  108.         }
  109.         
  110.     if (fd2p)
  111.         {
  112.         /* create listening socket */
  113.         *fd2p=s_socket(AF_INET,SOCK_STREAM,0);
  114.  
  115.         bzero((char *)&me, sizeof(me));
  116.         me.sin_family = AF_INET;
  117.         me.sin_port = htons(0);        /* any port */
  118.         
  119.         if (s_bind(*fd2p, (struct sockaddr *)&me, sizeof(me) ) < 0)
  120.             {
  121.             return -1;
  122.             }
  123.  
  124.         if (s_listen(*fd2p,1) < 0)
  125.             {
  126.             /* 
  127.              * s_listen is the routine that actuall puts the correct
  128.              * IP address to the socket. Up to this point, the socket
  129.              * has had an address of 0, port 0.
  130.              */
  131.             return -1;
  132.             }
  133.         /*
  134.          * Now we must fetch the number of the port so we can tell
  135.          * the rexecd where to find us.
  136.          */
  137.         melen=sizeof(me);
  138.         s_getsockname(*fd2p, (struct sockaddr *)&me , &melen);
  139.         sprintf(wbuf,"%d\0",(long)me.sin_port);    /* tell rexec where to hook up to */
  140.         }
  141.     else
  142.         *wbuf='\0';        /* pass an empty string for no stderr port */
  143.         
  144.     anErr = s_write (sockOut,wbuf,strlen(wbuf)+1);        /* write out string */
  145.     
  146.     DOERR
  147.     
  148.     if (fd2p)    /* do we need to accept? */
  149.         {
  150.         struct        timeval selectPoll;
  151.         fd_set        readfds;
  152.         
  153.         selectPoll.tv_sec=60;    /* block for one minute */
  154.         selectPoll.tv_usec=0;
  155.         FD_ZERO(&readfds);
  156.         FD_SET(*fd2p,&readfds);    /* only looking for connect on one socket */
  157.         
  158.         anErr = s_select(32, &readfds, (fd_set *)0,
  159.                 (fd_set *)0, &selectPoll);
  160.         
  161.         if (anErr < 1 )
  162.             return -1;            
  163.             
  164.         anErr = s_accept_once(*fd2p,(struct sockaddr *)&her,&herlen);
  165.         /*
  166.          * might want to check and make sure that the connected machine
  167.          * is the right one, but that seems a bit execessive.
  168.          */
  169.         DOERR
  170.         
  171.         }
  172.         
  173.     anErr = s_write (sockOut,user,strlen(user)+1);
  174.     DOERR
  175.     anErr = s_write (sockOut,passwd,strlen(passwd)+1);
  176.     DOERR
  177.     anErr = s_write (sockOut,cmd,strlen(cmd)+1);
  178.     DOERR
  179.     
  180.     /*
  181.      * Hey, wouldn't it be great if rexec sent encrypted passwords?
  182.      * And wouldn't it be great if it sent along a case of a really good beer?
  183.      * Like Keystone!
  184.      */
  185.      
  186.     anErr = s_read (sockOut,wbuf,1);    /* fetch answer */
  187.     DOERR
  188.     
  189.     if (*wbuf!=0)
  190.         {
  191.         errno = errno_long = EACCES;
  192.         return -1;  /* permission denied! */
  193.         }
  194.     
  195.     return sockOut;
  196.     }
  197.  
  198. /*
  199.  * Polls an exisiting stderr hookup from a previous rexec for any error
  200.  * text. If there is, it will be returned in str, up to strln bytes
  201.  *
  202.  * Assumes sock is connected properly and str is not null.
  203.  */
  204. int rexecerr(Int4 sock,char *str,Int4 strln)
  205.     {
  206.     fd_set    rfds;
  207.     struct    timeval tv;
  208.     int        selectcode;
  209.     
  210.     FD_ZERO(&rfds);
  211.     
  212.     FD_SET(sock,&rfds);
  213.     
  214.     tv.tv_sec=1;
  215.     tv.tv_usec=0;
  216.     
  217.     selectcode = s_select(sock+1,&rfds,(fd_set *)NULL,(fd_set *)NULL,&tv);
  218.     
  219.     if ( selectcode < 0 )
  220.         return -1;
  221.     else if ( !selectcode )
  222.         return 0;
  223.     else
  224.         if (s_read(sock,str,strln)<0)
  225.             return -1;
  226.         return 1;
  227.     
  228.     }